package com.example.caoben_back.config;

import com.example.caoben_back.entity.po.User;
import com.example.caoben_back.utils.JWTUtil;
import com.example.caoben_back.utils.RedisUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Component
public class JwtFilter implements Filter {

  @Autowired
private JWTUtil jwtUtil;
  
  @Autowired
  private RedisUtil redisUtil;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化操作
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        // 检查是否是公共路径（登录、注册等）
        String requestURI = httpRequest.getRequestURI();
        if (isPublicPath(requestURI) || "OPTIONS".equalsIgnoreCase(httpRequest.getMethod())) {
            chain.doFilter(request, response);
            return;
        }

        // 获取请求头中的token
        String token = httpRequest.getHeader("token");
        
        // 检查是否有token
        if (token == null || token.isEmpty()) {
            sendUnauthorizedResponse(httpResponse, "未提供token");
            return;
        }

        // 先从Redis中检查token是否已登出或失效
        String blacklisted = (String) redisUtil.get("blacklist_token:" + token);
        if ("invalid".equals(blacklisted)) {
            sendUnauthorizedResponse(httpResponse, "token已在黑名单中");
            return;
        }

        // 验证token是否有效
        if (!JWTUtil.verify(token, jwtUtil.getSecret())) {
            // 将无效token加入Redis黑名单，防止重复验证
            redisUtil.set("blacklist_token:" + token, "invalid", jwtUtil.getExpireTime()/1000);
            sendUnauthorizedResponse(httpResponse, "token无效或已过期");
            return;
        }

        // 将用户信息放入request属性，供后续Controller使用
        User user = JWTUtil.getPayload(token, User.class);
        httpRequest.setAttribute("user", user);

        chain.doFilter(request, response);
    }

    /**
     * 判断是否为公共路径
     */
    private boolean isPublicPath(String requestURI) {
        return requestURI.contains("/user/login") 
                || requestURI.contains("/user/register")
                ||requestURI.contains("/weather/province/list")
                || requestURI.contains("/post/list");
    }

/**
     * 发送未授权响应
     */
    private void sendUnauthorizedResponse(HttpServletResponse response, String message) throws IOException {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType("application/json;charset=UTF-8");

        Map<String, Object> result = new HashMap<>();
        result.put("code",HttpServletResponse.SC_UNAUTHORIZED);
        result.put("message", message);
        
        ObjectMapper objectMapper = new ObjectMapper();
        response.getWriter().write(objectMapper.writeValueAsString(result));
    }

    @Override
    public void destroy() {
       // 销毁操作
    }
}